package com.cictec.middleware.gps.engine;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;

import org.mvel2.MVEL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.cictec.middleware.commons.utils.Constants;
import com.cictec.middleware.commons.utils.DateUtils;
import com.cictec.middleware.gps.engine.position.PositionHandlerEvent;
import com.cictec.middleware.gps.service.BusDriverService;
import com.cictec.middleware.gps.service.BusTimingPointService;
import com.google.common.eventbus.Subscribe;

/**
 * 时间序列数据 判断是否历史数据 调用多线程接口执行分析
 * 
 * @author zhou qi
 *
 */
@Component
public class TimingPointEventListener {
	private static Logger logger = LoggerFactory.getLogger(TimingPointEventListener.class);

	@Autowired
	private TimeEventBus timeEventBus;
	@Autowired
	private BusInstanceEngine busInstanceEngine;
	@Autowired
	private BusTimingPointService busTimingPointService;
	@Autowired
	private BusDriverService busDriverService;
	
	
	@PostConstruct
	public void init() {
//		System.out.println("注册 TimingObjectEventListener 到 TimeEventBus");
		logger.debug("注册【TimingPointEventListener】到TimeEventBus， 监听器：TimingPointEventListener ---> 事件：TimingPointEvent");
		timeEventBus.register(this);

	}

	/**
	 * 只做是否历史数据判断
	 */
	@Subscribe
	public void onPosition(TimingPointEvent event) {
		TimingPoint timingPoint = event.getTimingObject();
//		isdef HISTORY_DATA
		String str = "isdef " + Constants.MSG_INFO_POSITION_HISTORY_DATA;
		Serializable compiled = MVEL.compileExpression(str);
		Boolean result = (Boolean) MVEL.executeExpression(compiled, timingPoint.getAttributes());
		if (!result) {
			
			// 判断数据是否是历史数据
			BusInstance busInstance = busInstanceEngine.getBusInstanceByDevCode(timingPoint.getDevCode());
			int timingSequentialSize = busInstance.getTimingSequential().size();	// 时序对象
			
			
			/* ***存储指定多个时序对象用于判定 start ****/
			if(timingSequentialSize > 11){
				List<TimingPoint> list = busInstance.getTimingSequential();
				List<TimingPoint> tmpList = new ArrayList<TimingPoint>();
				tmpList.addAll(list.subList(timingSequentialSize - 10, timingSequentialSize));
				busInstance.setTimingSequential(tmpList);
			}
//			busInstance.addTimingPoint(timingPoint);
			/* ***存储指定多个时序对象用于判定 end ****/
			
			// 第一个数据或者 当前数据时间大于busInstance的时间
			if (!isHiostoryData(busInstance, timingPoint)) {
				timingPoint.setHistoryFlag(Constants.MSG_INFO_POSITION_HISTORY_DATA_FLASE);// 设置为非历史数据标识
				busInstance.setTime(timingPoint.getTime());	// 设置当前时间
				busInstance.setAttributes(timingPoint.getAttributes());		// 设置属性值
				
				busTimingPointService.saveTimePoint(timingPoint);	// 保存位置信息原始数据到redis或历史中
			} else {
				
				// 只存补存数据标识，不做数据处理
				timingPoint.setHistoryFlag(Constants.MSG_INFO_POSITION_HISTORY_DATA_TRUE);
				
				// 只存储
				busTimingPointService.saveTimePoint(timingPoint);	// 保存位置信息原始数据到redis或历史中
				return;
			}
			
			busInstance.addTimingPoint(timingPoint);

			/*
			 * 事件变化处理
			 */
//			changeHandler(timingPoint);
			
			// 直接发送，不经过事件变化处理
			timeEventBus.post(new PositionHandlerEvent(new Date(), busInstance));
		}
	}
	
	/**
	 * 判断是否是历史数据
	 * @param busInstance
	 * @param timingPoint
	 * @return true:历史数据，false:非历史数据
	 */
	private boolean isHiostoryData(BusInstance busInstance, TimingPoint timingPoint) {
		
		
		Date currentInstanceTime = busInstance.getTime();
		Date pointTime = timingPoint.getTime();

		
		if(!DateUtils.getDate().equals(DateUtils.formatDate(pointTime))){
			// 是否是系统当天数据
			return true;
		}
		if(true){
			return false;
		}
				
		
		if(currentInstanceTime == null){
			// 如果该实例时间为空（即该对象刚生成），还没有位置信息
			currentInstanceTime = pointTime;
		}
		
		if(currentInstanceTime.getTime() <= pointTime.getTime()
				|| DateUtils.isCurrentSystemTime(pointTime, 120)					// 时间误差 小于120秒
//				|| DateUtils.secondInterval(currentInstanceTime, pointTime) <= 30	// 时间误差 小于30秒
				
				){
			return false;
		}
		
		return true;
	}
	
	/**
	 * 事件变化处理
	 * @param timingPoint
	 */
	protected void changeHandler(TimingPoint timingPoint){
		String str = "isdef " + Constants.MSG_INFO_POSITION_HISTORY_DATA + " && "
				+ Constants.MSG_INFO_POSITION_HISTORY_DATA + " == " + Constants.MSG_INFO_POSITION_HISTORY_DATA_FLASE;
		Serializable compiled = MVEL.compileExpression(str);
		Boolean result = (Boolean) MVEL.executeExpression(compiled, timingPoint.getAttributes());
		
		if (result) {
//			System.out.println("进入数据对比！");
			BusInstance busInstance = busInstanceEngine.getBusInstanceByDevCode(timingPoint.getDevCode());
			List<TimingPoint> point = busInstance.getTimingSequential();
			point.sort(new Comparator<TimingPoint>() {
				@Override
				public int compare(TimingPoint o1, TimingPoint o2) {
					int result = o1.getTime().compareTo(o2.getTime());
					return result;
				}
			});
			if (point.size() >= 2) {
				// 暂时没有用到状态变化 ，注视掉
				/*

				TimingPoint p1 = point.get(point.size() - 1);
				TimingPoint p2 = point.get(point.size() - 2);


				List<ChangedStatus> changedStatusList = new ArrayList<ChangedStatus>();

				System.out.println(p2.getStatus("POSITION_STATION_SEQ"));
				for (String s : p2.getStatus().keySet()) {
					if (p2.getStatus(s) == null) {
						System.out.println(s + "\t" + p2.getStatus(s));
					}
				}
				
				for (String s : p1.getStatus().keySet()) {
					if (p2.getStatus().containsKey(s) 
							&& !p2.getStatus(s).equals(p1.getStatus(s))) {
						changedStatusList.add(new ChangedStatus(s, p2.getStatus(s), p1.getStatus(s)));
					}
				}
				busInstance.setChangedStatusList(changedStatusList);
				 */

				busInstance.setAttributes(timingPoint.getAttributes());
				busInstance.setTime(timingPoint.getTime());

				busInstanceEngine.setBusInstance(busInstance);
			}
		}
	}
	
}
